package com.ruoyi.system.service.impl;

import com.alibaba.fastjson2.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.config.SimCardConfig;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.JSONObjectPro;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SnowFlakeIDGenerator;
import com.ruoyi.common.utils.http.CommonResponse;
import com.ruoyi.common.utils.http.HttpRequest;
import com.ruoyi.system.domain.EquipmentManagement;
import com.ruoyi.system.domain.SimCard;
import com.ruoyi.system.mapper.SimCardMapper;
import com.ruoyi.system.service.IEquipmentManagementService;
import com.ruoyi.system.service.ISimCardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * sim卡管理Service业务层处理
 * 
 * @author wp
 * @date 2023-08-10
 */
@Service
@Slf4j
public class SimCardServiceImpl extends ServiceImpl<SimCardMapper, SimCard> implements ISimCardService {
    @Autowired
    private SimCardMapper simCardMapper;
    @Autowired
    private SimCardConfig simCardConfig;
    @Autowired
    private IEquipmentManagementService equipmentManagementService;

    /**
     * 查询sim卡管理列表
     * 
     * @param simCard sim卡管理
     * @return sim卡管理
     */
    @Override
    @DataScope
    public List<SimCard> selectList(SimCard simCard) {
        return simCardMapper.list(simCard);
    }

    /**
     * 更新sim信息
     */
    @Override
    public void simCardUpdateAll(){
        long startTime = System.currentTimeMillis();
        log.info("开始执行sim卡信息更新任务");
        List<SimCard> apiSimCardList = new ArrayList<>();
        List<EquipmentManagement> equipmentList = equipmentManagementService.list(new QueryWrapper<EquipmentManagement>()
                .ne("sim_id", "")
                .isNotNull("sim_id"));
        int count = equipmentList.size();
        //确定调用接口的次数
        int pageCount = count / 50;
        if ((count % 50) > 0) {
            pageCount = pageCount + 1;
        }
        // 记录第三方接口调用次数
        int interfaceCount = 0;
        for (int i = 0; i < pageCount; i++) {
            interfaceCount++;
            //获取本次要调用接口的simId
            List<EquipmentManagement> thisTimeList = equipmentList.subList(i * 50, i == pageCount - 1 ? count : ((i + 1) * 50));
            Map<String, EquipmentManagement> simIdEquipmentMap = thisTimeList.stream().collect(Collectors.toMap(EquipmentManagement::getSimId, Function.identity()));
            JSONObjectPro paramJson = new JSONObjectPro().put("iccids", simIdEquipmentMap.keySet());
            String apiUrl = simCardConfig.getBatchUrl(paramJson.toJSONString());
            CommonResponse<List<SimCard>> response = HttpRequest.postJson(apiUrl, paramJson, new TypeReference<List<SimCard>>(){}.getType());
            List<SimCard> list = response.getData();
            if (!response.isSuccess() || ObjectUtils.isEmpty(list)) continue;
            //数据处理
            for (SimCard apiSimCard : list) {
                //查出来的结果有的跟iccid匹配，有的跟msisdn匹配，两个取其一匹配就行
                String simId = simIdEquipmentMap.containsKey(apiSimCard.getMsisdn()) ? apiSimCard.getMsisdn() : apiSimCard.getIccid();
                apiSimCard.setEquipmentId(simIdEquipmentMap.get(simId).getId());
                if (simIdEquipmentMap.containsKey(apiSimCard.getMsisdn()) && !apiSimCard.getMsisdn().equals(apiSimCard.getIccid())){
                    //设备sim_id用的之前的msisdn，更换为iccid，且删除本条SIM卡记录，下方会重新创建一条记录
                    EquipmentManagement equipment = simIdEquipmentMap.get(apiSimCard.getMsisdn());
                    equipment.setSimId(apiSimCard.getIccid()).setUpdateBy(UserConstants.ADMIN_ID);
                    equipmentManagementService.updateById(equipment);
                    simCardMapper.delete(new QueryWrapper<SimCard>().eq("msisdn", apiSimCard.getMsisdn()));
                }
            }
            apiSimCardList.addAll(list);
            //sim卡查询接口限定调用频率为60次/分钟，超过60次进行delay
            if (interfaceCount >= 60) {
                try {
                    TimeUnit.MINUTES.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                interfaceCount = 0;
            }
        }
        //此时已获取到所有sim卡信息
        if (!apiSimCardList.isEmpty()){
            //待新增的集合
            List<SimCard> insertSimList = new ArrayList<>();
            //待更新的集合
            List<SimCard> updateSimList = new ArrayList<>();
            Map<String, SimCard> existSimCardMap = simCardMapper.selectList(new QueryWrapper<>()).stream().collect(Collectors.toMap(SimCard::getIccid, Function.identity(), (existingValue, newValue) -> newValue));
            //更新、创建时间
            Date date = new Date();
            apiSimCardList.stream().forEach(i -> {
                i.setCreateTime(date);
                if (existSimCardMap.containsKey(i.getIccid())){
                    //当前SIM卡已存在，则更新
                    i.setId(existSimCardMap.get(i.getIccid()).getId());
                    i.setUpdateBy(UserConstants.ADMIN_ID);
                    updateSimList.add(i);
                }else {
                    //当前SIM卡不存在，则新增
                    insertSimList.add(i);
                }
            });
            saveBatch(insertSimList);
            log.info("sim卡新增成功，数量：" + insertSimList.size());
            updateBatchById(updateSimList);
            log.info("sim卡更新成功，数量：" + updateSimList.size());
        }
        log.info("sim卡信息更新任务执行结束，耗时：" + (System.currentTimeMillis() - startTime) + "秒");
    }

    /**
     * 更新单个sim信息
     */
    @Override
    public SimCard getSimCardInfo(String iccid){
        String apiUrl = simCardConfig.getSingleUrl(iccid);
        CommonResponse<SimCard> response = HttpRequest.get(apiUrl, null, SimCard.class);
        SimCard simCard = response.getData();
        if (!response.isSuccess() || simCard == null) throw new ServiceException("SIM卡不存在");
        //更新SIM卡信息
        simCardMapper.update(simCard, new QueryWrapper<SimCard>().eq("iccid", iccid));
        return simCard;
    }

}
